package com.dss.auto_deploy.util;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * 二维码生成
 *
 * @author: dongshoushan
 * @date:2024-04-25 15:45:03
 */
public class QRCodeGenerator {

    private static final int DEFAULT_SIZE = 500; // 二维码大小（像素）
    private static final float LOGO_SIZE_RATIO = 0.15f; // Logo大小占二维码大小的比例，这里使用0.25f表示四分之一
    private static final int MARGIN = 5; // 二维码边距（像素）
    private static final String BOTTOM_TEXT_FONT_NAME = "宋体"; // 底部文字字体
    private static final int BOTTOM_TEXT_FONT_SIZE = 16; // 底部文字字号
    private static final Color BOTTOM_TEXT_COLOR = Color.cyan; // 底部文字颜色

    /**
     * 生成带logo和底部文字的二维码图片
     *
     * @param content       二维码内容
     * @param outputFilePath 输出二维码图片的完整路径
     * @param logoPath      二维码中间的logo图片路径
     * @param bottomText    底部文字
     * @throws IOException 如果文件读写过程中发生错误
     */
    public static void generateQRCodeWithLogoAndText(String content, String outputFilePath, String logoPath, String bottomText,float logoSizeRatio) throws IOException {
        // 生成二维码矩阵
        BitMatrix bitMatrix = encodeQRCode(content);

        // 获取二维码的宽高
        int qrWidth = bitMatrix.getWidth();
        int qrHeight = bitMatrix.getHeight();

        // 创建BufferedImage对象，用于绘制二维码、logo和底部文字
        BufferedImage image = new BufferedImage(qrWidth + 2 * MARGIN, qrHeight + 2 * MARGIN + BOTTOM_TEXT_FONT_SIZE + MARGIN, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = image.createGraphics();

        // 设置背景色为白色
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, image.getWidth(), image.getHeight());

        // 绘制二维码
        graphics.setColor(Color.BLACK);
        for (int i = 0; i < qrWidth; i++) {
            for (int j = 0; j < qrHeight; j++) {
                if (bitMatrix.get(i, j)) {
                    graphics.fillRect(MARGIN + i, MARGIN + j, 1, 1);
                }
            }
        }

        // 添加logo
        Image logoImage = ImageIO.read(new File(logoPath));
        double scaleFactor = logoSizeRatio * qrWidth / logoImage.getWidth(null);
        int logoWidth = (int) Math.round(logoImage.getWidth(null) * scaleFactor);
        int logoHeight = (int) Math.round(logoImage.getHeight(null) * scaleFactor);
        graphics.drawImage(logoImage, (qrWidth - logoWidth) / 2 + MARGIN, (qrHeight - logoHeight) / 2 + MARGIN, logoWidth, logoHeight, null);

        // 添加底部文字
        graphics.setFont(new Font(BOTTOM_TEXT_FONT_NAME, Font.PLAIN, BOTTOM_TEXT_FONT_SIZE));
        graphics.setColor(BOTTOM_TEXT_COLOR);
        graphics.drawString(bottomText, (image.getWidth() - graphics.getFontMetrics().stringWidth(bottomText)) / 2, image.getHeight() - MARGIN);

        // 保存二维码图片
        ImageIO.write(image, "PNG", new File(outputFilePath));
    }

    /**
     * 编码二维码
     *
     * @param content 二维码内容
     * @return 生成的二维码BitMatrix
     */
    private static BitMatrix encodeQRCode(String content) {
        try {
            Map<EncodeHintType, Object> hints = new HashMap<>();
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
            hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name());
            hints.put(EncodeHintType.MARGIN, MARGIN);

            QRCodeWriter writer = new QRCodeWriter();
            return writer.encode(content, BarcodeFormat.QR_CODE, DEFAULT_SIZE, DEFAULT_SIZE, hints);
        } catch (Exception e) {
            throw new RuntimeException("Failed to encode QR code", e);
        }
    }
}